package com.ruicar.afs.cloud.basic.proceeds.debit.controller;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruicar.afs.cloud.basic.common.entity.BasicBankCard;
import com.ruicar.afs.cloud.basic.common.entity.BasicContractCustRelation;
import com.ruicar.afs.cloud.basic.common.entity.BasicCustBaseInfo;
import com.ruicar.afs.cloud.basic.common.entity.BasicMainInfo;
import com.ruicar.afs.cloud.basic.common.service.*;
import com.ruicar.afs.cloud.basic.proceeds.debit.condition.SingleDebitCondition;
import com.ruicar.afs.cloud.basic.proceeds.debit.entity.BasicDebitRecord;
import com.ruicar.afs.cloud.basic.proceeds.debit.service.BasicDebitBatchService;
import com.ruicar.afs.cloud.basic.proceeds.debit.service.BasicDebitRecordService;
import com.ruicar.afs.cloud.basic.proceeds.debit.vo.SingleDebitReadyVo;
import com.ruicar.afs.cloud.batch.service.AfsBatchInfoService;
import com.ruicar.afs.cloud.common.core.util.IResponse;
import com.ruicar.afs.cloud.common.modules.contract.enums.ContractStatusEnum;
import com.ruicar.afs.cloud.common.modules.contract.enums.DebitStatusEnum;
import com.ruicar.afs.cloud.common.modules.contract.enums.FeeTypeEnum;
import com.ruicar.afs.cloud.common.modules.contract.enums.PersonRoleTypeEnum;
import com.ruicar.afs.cloud.common.util.EmptyUtils;
import com.ruicar.afs.cloud.components.datadicsync.DicHelper;
import com.ruicar.afs.cloud.components.datadicsync.dto.DicDataDto;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * <p>Description: 单笔扣款相关接口</p>
 *
 * @author ZC.GUO
 * @version 1.0
 * @date create on 2020-06-30 09:32
 */
@Slf4j
@RestController
@Api("单笔扣款")
@RequestMapping("/singleDebit")
public class SingleDebitController {

    @Autowired
    private BasicDebitRecordService basicDebitRecordService;

    @Autowired
    private BasicCustBaseInfoService basicCustBaseInfoService;

    @Autowired
    private BasicDebitBatchService basicDebitBatchService;

    @Autowired
    private BasicContractCustRelationService basicContractCustRelationService;
    @Autowired
    private BasicMainInfoService basicMainInfoService;
    @Autowired
    private BasicDebitInfoService basicDebitInfoService;
    @Autowired
    private BasicBankCardService basicBankCardService;
    @Autowired
    private AfsBatchInfoService afsBatchInfoService;

    public Date getBatchDate(){
        return DateUtil.parse(afsBatchInfoService.getSystemBatchInfo("icos").getBatchDate(), DatePattern.PURE_DATE_PATTERN);
    }



    /**
     * 分页查询可进行单笔代扣的合同
     * @author ZC.GUO
     * @param
     * @return
     */
    @PostMapping(value = "/getDebitContract")
    @ApiOperation(value = "分页查询可进行单笔代扣的合同")
    public IResponse<IPage<SingleDebitReadyVo>> queryDebitBatchDetailList(@ModelAttribute SingleDebitCondition singleDebitCondition) {

        /**  处理客户姓名查询条件 by ZC.GUO  **/
        if (!StringUtils.isEmpty(singleDebitCondition.getCustName())){
            List<String> contractList = basicCustBaseInfoService.selectContractNoByCustName(singleDebitCondition.getCustName().trim());
            if (CollectionUtil.isNotEmpty(contractList)){
                singleDebitCondition.setContractList(contractList);
            }else {
                /**  对空集合进行预处理 by ZC.GUO  **/
                List<String> emptyList = new ArrayList<>();
                emptyList.add("");
                singleDebitCondition.setContractList(emptyList);
            }
        }
        /**  处理合同号 **/
        if (!StringUtils.isEmpty(singleDebitCondition.getContractNo())){
            singleDebitCondition.setContractNo(singleDebitCondition.getContractNo().trim());
        }
        Page page = new Page(singleDebitCondition.getPageNumber(), singleDebitCondition.getPageSize());
        IPage<SingleDebitReadyVo> singleDebitReadyVoIPage = basicDebitRecordService.selectSingleDebitReadyContract(page,singleDebitCondition);
        if (ObjectUtil.isNotNull(singleDebitReadyVoIPage)){
            if (CollectionUtil.isNotEmpty(singleDebitReadyVoIPage.getRecords())){
                /**  其他相关信息数据封装 by ZC.GUO  **/

                for (SingleDebitReadyVo singleDebitReadyVo :singleDebitReadyVoIPage.getRecords()){
                    BasicContractCustRelation basicContractCustRelation = basicContractCustRelationService.getOne(Wrappers.<BasicContractCustRelation>query().lambda()
                            .eq(BasicContractCustRelation::getContractNo, singleDebitReadyVo.getContractNo()).eq(BasicContractCustRelation::getCustRole , PersonRoleTypeEnum.MAIN_PERSON));
                    if (EmptyUtils.isEmpty(basicContractCustRelation)){
                        basicContractCustRelation = new BasicContractCustRelation();
                    }
                    BasicCustBaseInfo custBaseInfo = basicCustBaseInfoService.getOne(Wrappers.<BasicCustBaseInfo>query().lambda()
                            .eq(BasicCustBaseInfo::getCustNo,basicContractCustRelation.getCustNo())
                    );
                    if (ObjectUtil.isNotNull(custBaseInfo)){
                        /**  客户姓名、手机号码 by ZC.GUO  **/
                        singleDebitReadyVo.setCustName(custBaseInfo.getCustName());
                        singleDebitReadyVo.setPhone(custBaseInfo.getPhone());
                    }
                    /**  未收金额 = 应收金额-已收金额 by ZC.GUO  **/
                    singleDebitReadyVo.setUnSucceedAmt(singleDebitReadyVo.getAmount().subtract(singleDebitReadyVo.getSucceedAmt()));

                    /**  待扣款明细 by ZC.GUO  **/
                    List<BasicDebitRecord> debitRecordList = basicDebitRecordService.list(Wrappers.<BasicDebitRecord>query().lambda()
                            .eq(BasicDebitRecord::getContractNo,singleDebitReadyVo.getContractNo())
                            .eq(BasicDebitRecord::getDebitStatus, DebitStatusEnum.mayDebit)
                            .isNull(BasicDebitRecord::getBatchId)
                    );
                    if (CollectionUtil.isNotEmpty(debitRecordList)){
                        singleDebitReadyVo.setRecordList(debitRecordList);
                    }else{
                        singleDebitReadyVo.setRecordList(new ArrayList<>());
                    }
                }
            }
        }
        return IResponse.success(singleDebitReadyVoIPage);
    }

    @PostMapping("/singleDebitSend")
    @ApiOperation(value = "发送单笔代扣")
    public IResponse<String> singleDebitSend(@ModelAttribute SingleDebitCondition singleDebitCondition){


        if (ObjectUtils.isNotEmpty(singleDebitCondition.getContractNo())){
            /**  无正在扣款指令 by ZC.GUO  **/
            List<BasicDebitRecord> goingRecord = basicDebitRecordService.list(Wrappers.<BasicDebitRecord>query().lambda()
                    .eq(BasicDebitRecord::getContractNo,singleDebitCondition.getContractNo())
                    .isNotNull(BasicDebitRecord::getBatchId)
            );
            if (EmptyUtils.isNotEmpty(goingRecord)){
                return IResponse.fail("该合同正在扣款，请稍后再试");
            }
            BasicMainInfo mainInfo = basicMainInfoService.getOne(Wrappers.<BasicMainInfo>query().lambda()
                    .eq(BasicMainInfo::getContractNo,singleDebitCondition.getContractNo())
            );
            /**  合同已结清，不许扣款 by ZC.GUO  **/
            if (EmptyUtils.isNotEmpty(mainInfo)){
                if (ContractStatusEnum.advanceSettle.equals(mainInfo.getContractStatus()) || ContractStatusEnum.normalSettle.equals(mainInfo.getContractStatus())){
                    return IResponse.fail("该合同已结清，不允许扣款");
                }
            }else{
                return IResponse.fail("合同号不存在");
            }

            List<BasicDebitRecord> preRecord = basicDebitRecordService.list(Wrappers.<BasicDebitRecord>query().lambda()
                    .eq(BasicDebitRecord::getContractNo,singleDebitCondition.getContractNo())
                    .eq(BasicDebitRecord::getFeeType, FeeTypeEnum.advanceSettle)
            );
            /**  没有提前结清扣款指令 by ZC.GUO  **/
            if (EmptyUtils.isEmpty(preRecord)){
                BigDecimal arrears = basicDebitInfoService.getCurrentArrears(singleDebitCondition.getContractNo(),this.getBatchDate());
                if (arrears.compareTo(BigDecimal.ZERO)<=0){
                    return IResponse.fail("该合同无欠款，不允许扣款");
                }
            }

            BasicBankCard bankCard = basicBankCardService.getOne(Wrappers.<BasicBankCard>query().lambda()
                    .eq(BasicBankCard::getContractNo,mainInfo.getContractNo())
            );
            if (EmptyUtils.isEmpty(bankCard)){
                return IResponse.fail("该合同无预留扣款卡，不可扣款");
            }
            String chlCd = null;
            Map<String, List<DicDataDto>> dicMap = DicHelper.getDicMaps("mappingBank");
            List<DicDataDto> dicList=dicMap.get("mappingBank");
            for (DicDataDto dto : dicList){
                if(dto.getValue().equals(bankCard.getBankCode())){
                    chlCd = dto.getTitle();
                }
            }
            if (EmptyUtils.isEmpty(chlCd)){
                return IResponse.fail("无此银行代码的通道，银行编码："+bankCard.getBankCode());
            }

            if (basicDebitBatchService.generateBatchAndSendByContractNo(singleDebitCondition.getContractNo(),this.getBatchDate())){
                return IResponse.success("扣款请求发送成功");
            }else {
                return IResponse.fail("扣款请求发送失败");
            }
        }else{
            return IResponse.fail("合同号不能为空");
        }
    }
}
